package com.forestar.mapControl.utils.mapConvert;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;

import com.forestar.mapControl.mappool.MapCachePool2;
import com.forestar.mapControl.mappool.MzTileBean;
import com.forestar.mapControl.mapview.CacheCanvas;
import com.forestar.mapControl.mapview.multitouch.TestTextureViewRefreshListener;
import com.forestar.mapControl.utils.LogD;
import com.forestar.mapControl.utils.bitmapcache.CacheableBitmapDrawable;
import com.forestar.mapControl.utils.mapConvert.convert.ConvertHelper2;
import com.forestar.mapControl.utils.mapConvert.geometry.Envelope;
import com.forestar.mapControl.utils.mapConvert.geometry.GeoPoint;
import com.forestar.mapControl.utils.mapConvert.task.ConfigurablePriorityThreadFactory;
import com.forestar.mapControl.utils.mapConvert.task.DrawForTask;
import com.forestar.mapControl.utils.tile.TileCoord;
import com.forestar.mapControl.utils.tile.TileSchema;
import com.forestar.mapControl.utils.tile.TilesIndexBound;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import static com.forestar.mapControl.mappool.MzTileBean.LOAD_STATE_COMPLETE;
import static com.forestar.mapControl.mappool.MzTileBean.LOAD_STATE_FAIL;
import static com.forestar.mapControl.mappool.MzTileBean.LOAD_STATE_LOADING;
import static com.forestar.mapControl.mappool.MzTileBean.LOAD_STATE_NO;
import static com.forestar.mapControl.utils.mapConvert.convert.ConvertHelper2.TIANDITU_SAT_KEY2;

/**
 * created by  xzk
 * 2020/7/27   17:02
 * 说明:  从这里，开始解析地图位置，发起任务请求
 */
public class MapConvertForGoogle {
//
////    private CacheCanvas targetCanvas;
//    private List<CacheCanvas> cacheCanvasList;
//    protected TileSchema tileSchema;
//    private float screenPPI;
//
//    private Paint tempPaint = new Paint();
//
//    private TestTextureViewRefreshListener refreshListener;
//
//    //当前刷新状态（根据任务是否完成来定）  默认是完成状态
//    private boolean refreshTaskComplete = true;
//    private ExecutorService loadTilePool;
//    //单独一个计算线程
//    private volatile ExecutorService sumTilePool;
//    //读取ui的线程池
//    private volatile ExecutorService loadCacheTilePool;
//    private final ConvertHelper2 convertHelper;
//
//    private int maxTaskNum = 20;
//    private List<Bitmap> bitmapTempList;
//
//
//    public List<String> getMillSum() {
//        if(null == drawTestTask||null == drawTestTask.getMillSum()){
//            return new ArrayList<>();
//        }else {
//            return drawTestTask.getMillSum();
//        }
//    }
//
//    public void initData(TileSchema tileSchema,CacheCanvas targetCanvas,TestTextureViewRefreshListener refreshListener){
//        this.tileSchema = tileSchema;
//        this.refreshListener = refreshListener;
//    }
//
//    public void initData(TileSchema tileSchema,CacheCanvas targetCanvas,List<CacheCanvas> tempCanvasList,TestTextureViewRefreshListener refreshListener){
//        this.tileSchema = tileSchema;
//        this.cacheCanvasList = tempCanvasList;
//        this.refreshListener = refreshListener;
//    }
//
//    //todo 有多数核心线程时，加载速度飞快
//    public MapConvertForGoogle(){
//
//        loadTilePool = new ThreadPoolExecutor(0, 60, 10L, TimeUnit.MILLISECONDS,
//                new LinkedBlockingQueue<Runnable>(), new ConfigurablePriorityThreadFactory(Thread.NORM_PRIORITY, "加载影像"), new ThreadPoolExecutor.DiscardOldestPolicy());
//
////        loadTilePool = Executors.newFixedThreadPool(maxTaskNum,
////                new ConfigurablePriorityThreadFactory(Thread.MAX_PRIORITY, "加载影像"));
//        sumTilePool = Executors.newSingleThreadExecutor(
//                new ConfigurablePriorityThreadFactory(Thread.NORM_PRIORITY, "计算区域"));
//        loadCacheTilePool = Executors.newFixedThreadPool(10,
//                new ConfigurablePriorityThreadFactory(Thread.NORM_PRIORITY, "绘制缓存线程"));
//        convertHelper = new ConvertHelper2();
//    }
//
//    public float getScreenPPI(Context mContext) {
//        MapCachePool2.getInstance().setmContextAndInitCache(mContext);
//        this.screenPPI = mContext.getResources().getDisplayMetrics().xdpi;
//        return this.screenPPI;
//    }
//
//    private DrawForTask drawTestTask;
//    int numTask = 0;
////todo 刷新ui，这里保持14ms刷新一次，目前的闪烁的效果已明显减少
//    public void refreshUI(MapViewTransform transform){
//        //在这里降低了刷新ui频率，有效降低了地图闪烁的情况
//        if(hasTaskNum.get()<1){
////            //以原子方式将当前值增加一。
//            this.transformNew =transform;
//            hasTaskNum.incrementAndGet();
//            loadCacheTilePool.execute(sumTileAreaTask);
//            numTask++;
//            LogD.d("已经产生的任务数量："+numTask);
//        }
//    }
//
//
////todo 当前刷新ui的任务数量(这里做任务控制，达到 0-14ms之间的刷新任务，完全拦截住)
//    private AtomicInteger hasTaskNum = new AtomicInteger(0);
//    private MapViewTransform transformNew;
//    //todo 提取到子线程加载，能有效减少由于主线程计算瓦片引起的白屏问题
//
//    Paint temppaint = new Paint();
//    private void drawForCache(){
//        int width = DrawForTask.widthScreen;
//        int height = DrawForTask.heightScreen;
//        Rect dstCanvasRect = new Rect(0,0,width,height);
//        CacheCanvas cacheCanvas0 = cacheCanvasList.get(0);
//        CacheCanvas cacheCanvas1 = cacheCanvasList.get(1);
//        //加锁，控制一次加载到缓存的数量，避免混乱
//        synchronized (cacheCanvas0.lockObject){
//            cacheCanvas0.getCanvas().drawBitmap(cacheCanvas1.getBitmap(), null, dstCanvasRect, temppaint);
//        }
//        if(refreshListener != null){
//            refreshListener.refreshTextureView();
//        }
//    }
//
//    private Runnable sumTileAreaTask = new Runnable() {
//
//        @Override
//        public void run() {
//            int level = tileSchema.getBestLevelByResolution(transformNew.getResolutionInMapUnit(), screenPPI);
//            if (level == -1) {
//                return;
//            }
//            Envelope envlope = transformNew.getViewBound();
//            TilesIndexBound tilesBound = tileSchema.getTilesIndexBound(level, envlope.getXMin(), envlope.getXMax(), envlope.getYMin(), envlope.getYMax());
//            LogD.d("本次绘制的区域:"+tilesBound.toString()+"----");
//            if (tilesBound.isEmpty()) {
//                return ;
//            }
//
//            //缓存层的canvas和textureView在绘制的时候，一起重置页面，即可实现减少残留的效果
//            //每次耗时在5-8ms，非常不能接受
//            //把两个缓存都清屏，避免绘制过程中丢失缓存，但是在
////            CacheCanvas cacheCanvas1 = cacheCanvasList.get(1);
//            CacheCanvas cacheCanvas0 = cacheCanvasList.get(0);
//
//            cacheCanvas0.getCanvas().translate(transformNew.getDistanceX(),transformNew.getDistanceY());
//            cacheCanvas0.getCanvas().drawColor(Color.RED);
//            //看看偏移的多不多
//
////            cacheCanvas1.reSize(transformNew,widthScreen, heightScreen);
////            cacheCanvas1.reSize(transformNew,widthScreen, heightScreen);
//
//            List<CacheableBitmapDrawable> tempList = new ArrayList<>();
////            //总共1层
//            long start = System.currentTimeMillis();
//            long endForCanvasMill=0;
//
//            int xMore = 4;
//            int yMore = 4;
//
//            //计算中心点
//            int middleY=(tilesBound.maxTileY-tilesBound.minTileY)/2+tilesBound.minTileY;
//            int middleX=(tilesBound.maxTileX-tilesBound.minTileX)/2+tilesBound.minTileX;
//
//            //先计算中心的区域
//            int centerLeft = middleX-2;
//            int centerRight = middleX+2;
//            int centerTop = middleY-2;
//            int centerBottom = middleY+2;
//            //先清除下上一屏需要的数据
//            MapCachePool2.getInstance().getNoScreenTile().clear();
////            ;MapCachePool2.getInstance().getAllScreenTileHasLoad()
//            //这里gc一下
//            MapCachePool2.getInstance().removeAllTask();
//
//            for (int y = centerTop ; y <= centerBottom ; y++) {
//                for (int x = centerLeft ; x <= centerRight ; x++) {
//                    final MzTileBean tile = new MzTileBean(TIANDITU_SAT_KEY2, tilesBound.level, x, y);
//                    drawTile(tile,cacheCanvas0);
//                    MapCachePool2.getInstance().getNoScreenTile().add(tile.getCacheKey());
//                    CacheableBitmapDrawable forShow = MapCachePool2.getInstance().getBitmapForShow(tile);
//                    //在循环中就直接绘制了
//                    if(null != forShow ){
//                        tempList.add(forShow);
//                    }
//                }
//            }
//
//            //在屏幕边缘的区域
//            for (int y = tilesBound.minTileY ; y <= tilesBound.maxTileY ; y++) {
//                for (int x = tilesBound.minTileX ; x <= tilesBound.maxTileX ; x++) {
//                    if(y>centerTop && y<centerBottom && x > centerLeft && x < centerRight ){
//                        continue;
//                    }
//                    final MzTileBean tile = new MzTileBean(TIANDITU_SAT_KEY2, tilesBound.level, x, y);
//                    drawTile(tile,cacheCanvas0);
//                    MapCachePool2.getInstance().getNoScreenTile().add(tile.getCacheKey());
//                    CacheableBitmapDrawable forShow = MapCachePool2.getInstance().getBitmapForShow(tile);
//                    //在循环中就直接绘制了
//                    if(null != forShow ){
//                        tempList.add(forShow);
//                    }
//                }
//            }
//
//            //放入屏幕外围的预加载任务
//            for (int y = tilesBound.minTileY-yMore; y <= tilesBound.maxTileY+yMore; y++) {
//                for (int x = tilesBound.minTileX-xMore; x <= tilesBound.maxTileX+xMore; x++) {
//                    //接入外围区域
//                    if(y>tilesBound.minTileY && y<tilesBound.maxTileY && x > tilesBound.minTileX && x < tilesBound.maxTileX ){
//                        continue;
//                    }
//                    final MzTileBean tile = new MzTileBean(TIANDITU_SAT_KEY2, tilesBound.level, x, y);
//                    drawTile(tile,cacheCanvas0);
////                    //外围区域不绘制，只预加载
//                   MapCachePool2.getInstance().putForRequestTaskIfNeed(tile);
//                }
//            }
//
//            //遍历绘制
//            for(CacheableBitmapDrawable forShow: tempList){
////                        forShow.draw(targetCanvas.getCanvas());
////                endForCanvasMill = System.currentTimeMillis();
////                long offDiff = endForCanvasMill - start;
////                if(offDiff>40){
////                    drawForCache();
////                    start = endForCanvasMill;
////                }
//                if(!MapCachePool2.getInstance().getAllScreenTileHasLoad().add(forShow.getUrl())){
//                    cacheCanvas0.getCanvas().drawBitmap(forShow.getBitmap(),null,forShow.getBounds(),tempPaint);
////                    MapCachePool2.getInstance().getAllScreenTileHasLoad().add(forShow.getUrl());
//                }
//            }
//
//            long endDraw = System.currentTimeMillis();
////        //一次性绘制到界面上的效率太低了，每次 3-5之间，可以忍受
//            LogD.d("单次拉取瓦片:效率：" + (endDraw - start) + ".");
////            drawForCache();
//
//            //启动一个加载任务，放入线程池中，，，怎么放到线程池的呢？  最大不超过maxTaskNum个任务
//            //启动任务前，先关闭之前的所有任务
//            //todo 慢启动策略，，，，避免一个任务多次下发的情况
//            //todo 线程池任务下发做限制，极大避免了重复启动线程池，占用cpu的问题
//            //todo 这里做优化，尽量避免在灵活滑动过程中，增加多余任务（一旦出现增加多余任务将会是灾难级的数量递增规模）
//            //  原来的固定线程数，不知道为什么不走了
////            int size = MapCachePool2.getInstance().getmWorking().size();
//           //添加一个数字  开始加载
//            for (int i = 0; i < 30; i++) {
//                loadTilePool.execute(new LoadTileTask());
//            }
////        //一次性绘制到界面上的效率太低了，每次 45-48之间，甚至更高（这里是必须优化下来的）
//        }
//    };
//
////    创建线程池，不停的往缓存画布上增量绘制图形，试试看能不能随着手指移动换图形
//
//    private void refreshForLoadComplete(){
//        refreshListener.reLoadScreenTile();
//    }
////通过关系，计算瓦片在哪个位置
//    public void drawTile(MzTileBean tile, CacheCanvas cacheCanvas )
//    {
//        MapViewTransform transform = cacheCanvas.getTransform();
//        final Rect mTileRect = new Rect();
//        TileCoord tileCoord = tileSchema.getTileCoord(tile.getLevel(), tile.getX(), tile.getY());
//        // 换算到屏幕坐标
//        GeoPoint gpUpperLeft;
//        GeoPoint gpLowerRight;
//        gpUpperLeft = new GeoPoint(tileSchema.getCoordinateSystem(), tileCoord.minX, tileCoord.maxY);
//        gpLowerRight = new GeoPoint(tileSchema.getCoordinateSystem(), tileCoord.maxX, tileCoord.minY);
//        PointF upperLeft = transform.mapPoint2ScreenPoint(gpUpperLeft);
////        //地图点进行偏移
////        upperLeft.x = upperLeft.x+transformNew.getDistanceX();
////        upperLeft.y = upperLeft.y+transformNew.getDistanceY();
//        PointF lowerRight = transform.mapPoint2ScreenPoint(gpLowerRight);
////        //地图点进行偏移
////        lowerRight.x = lowerRight.x+transformNew.getDistanceX();
////        lowerRight.y = lowerRight.y+transformNew.getDistanceY();
//
//        mTileRect.set((int)upperLeft.x
//                , (int) upperLeft.y
//                , (int) lowerRight.x
//                , (int) lowerRight.y);
//        //保存当前图片显示的区域
//        tile.setTileRect(mTileRect);
//    }
//
//    //保存当前边界，以及，更新边界信息 算法(osmdroid是如何做到，边界时敏感的问题)
//
//    private int taskCompleteNum =0;
//    /**
//     * 加载任务执行线程
//     *
//     * 只执行加载瓦片到内存中，并不进行图片显示
//     */
//    private class LoadTileTask implements Runnable {
//        @Override
//        public void run() {
//            MzTileBean workTask = MapCachePool2.getInstance().getFirstWorkTask();
//            if (null != workTask && workTask.getState() == LOAD_STATE_NO) {
//                LogD.d("下载：执行下载任务："+workTask.getCacheKey());
//                workTask.setState(LOAD_STATE_LOADING);
//                CacheableBitmapDrawable singleTile = convertHelper.getSingleTile(workTask);
//                if(null != singleTile && singleTile.isBitmapValid()){
////                    //todo 拉取完毕，存入缓存  ，使用三级缓存时，就不适用临时缓存了
////                    MapCachePool2.getInstance().putBitmap(workTask,singleTile);
//                    //todo 通知主线程更新ui，线程内不更新ui（如果在线程内更新ui，会导致清屏行为无法使用，引起只有当前线程的瓦片展示这种奇怪问题）
//                    workTask.setState(LOAD_STATE_COMPLETE);
//                    MapCachePool2.getInstance().removeTask(workTask);
//                    taskCompleteNum++;
//
//                    CacheCanvas cacheCanvas0 = cacheCanvasList.get(0);
//                    singleTile.setBounds(workTask.getTileRect());
//                    singleTile.draw(cacheCanvas0.getCanvas());
////                    LogD.d("放入下载任务:下载完成任务数量:"+taskCompleteNum+"<剩余任务量：>"+MapCachePool2.getInstance().getmWorking().size());
////                    //是屏幕需要的数据
//                    //&& MapCachePool2.getInstance().isInScreen(workTask.getCacheKey())
////                    if(null != refreshListener ){
////                        refreshListener.reLoadScreenTile();
////                    }
//                }else {
//                    workTask.setState(LOAD_STATE_FAIL);
//                }
//                loadTilePool.execute(new LoadTileTask());
////                long end = System.currentTimeMillis();
////                LogD.d("地图效率，图:"+workTask.getCacheKey()+"：获取用时2："+(end-end1));
//                //todo 继续在线程池中放入任务
//                //todo 同一时间只有一个任务能够放入线程池(按照任务叠加新增，只需要3伦左右，就能把全部任务加载上)
////                long end = System.currentTimeMillis();
////                LogD.d("地图效率，图:"+workTask.getCacheKey()+"：加载用时："+(end-start));
//            } else {
//                //经常会出现，地图上有两块，一块，不显示，但是已经缓存在缓存中了
//                LogD.d("地图效率 没有任务了:"+(workTask==null?"":(workTask.getCacheKey()+workTask.getState())));
//
//                //加三次，以后再也不能来绘制了
////                hasTaskNum.incrementAndGet();
////                hasTaskNum.incrementAndGet();
////                hasTaskNum.incrementAndGet();
//            }
//        }
//
//    }

}
